package com.ruoyi.xuexiao.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.constant.*;
import com.ruoyi.constant.v3.ScztV3Enum;
import com.ruoyi.xuexiao.domain.entity.*;
import com.ruoyi.xuexiao.domain.param.*;
import com.ruoyi.xuexiao.domain.vo.*;
import com.ruoyi.xuexiao.mapper.*;
import com.ruoyi.xuexiao.service.KsJbxxhzxService;
import com.ruoyi.xuexiao.service.KsTcsService;
import io.netty.util.internal.StringUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 矿山基本信息汇总表Service实现层
 *
 * @author 齐浩宽
 * @since 2024-05-23 14:42:18
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class KsJbxxhzxServiceImpl extends ServiceImpl<KsJbxxhzMapper, KsJbxxhz> implements KsJbxxhzxService {

    // 矿山基本信息汇总表控制层
    private KsJbxxhzMapper ksJbxxhzMapper;

    //矿山底数抽查-抽取记录控制层
    private KsSsjCqjlMapper ksSsjCqjlMapper;

    //矿山底数抽查记录-抽取结果控制层
    private KsSsjCqjgMapper ksSsjCqjgMapper;

    //行政区控制层
    private BasicRegionMapper basicRegionMapperl;

    // 矿山图层管理业务层
    private KsTcsService ksTcService;

    //经济类型控制层
    private ZdJjLxMapper zdJjLxMapper;

    //矿山文件控制层
    private  KsFileMapper ksFileMapper;

    //遥感检测图控制层
    private KsYgJctMapper ksYgJctMapper;


    KsDomMapper ksDomMapper;

    /**
     * 查询矿山基本信息汇总表 抽查数据
     *
     * @author 齐浩宽
     * @since 2024年5月27日17:06:12
     */
    @Override
    public List<KsJbxxhzVo> getKsJbxhz(KsJbxxhzParam ksJbxxhzVo) {
        // 筛选条件
        LambdaQueryWrapper<KsSsjCqjl> wrapper = new LambdaQueryWrapper<KsSsjCqjl>()
                .eq(KsSsjCqjl::getCqwc, KsSsjCqjlStatusEnum.COMPLETED.getCode())
                .eq(KsSsjCqjl::getYear, ksJbxxhzVo.getYear());
        boolean exists = ksSsjCqjlMapper.exists(wrapper);
        // 判断当前年份是否被抽取
        if (!exists){
            return drawingSpecificMethod(ksJbxxhzVo);
        }else {
            throw new ServiceException("该年份已抽取");
        }
    }

    /**
     * 计算百分比 默认值为20
     * @author 齐浩宽
     */
    private KsJbxxhzParam calculateThePercentage(KsJbxxhzParam ksJbxxhzVo){
        //判断是否为空
        if (ksJbxxhzVo.getTheStatusIsNumberOfRecordsProduced() == null){
            //随机展示20-25条状态为生产
            ksJbxxhzVo.setTheStatusIsNumberOfRecordsProduced(new Random().nextInt(6)+20);
        }else {
            //计算百分比
            int round = (int) Math.round(
                    (double) ksJbxxhzVo.getTheStatusIsNumberOfRecordsProduced()
                            / 100 * ksJbxxhzVo.getTotalNumberOfMines()
            );
            ksJbxxhzVo.setTheStatusIsNumberOfRecordsProduced(round);
        }
        return ksJbxxhzVo;
    }

    /**
     * 记录表具体添加业务方法
     * @author 齐浩宽
     */
    private List<KsJbxxhzVo> drawingSpecificMethod(KsJbxxhzParam ksJbxxhzVo) {
        //返回子集数据集合
        List<KsJbxxhzVo> dtos = new ArrayList<>();
        //获取用户id
        Long id = SecurityUtils.getUserId();
        KsJbxxhzParam param = calculateThePercentage(ksJbxxhzVo);
        KsSsjCqjl cqjl = new KsSsjCqjl();
        cqjl.setName("双随机、一公开抽取记录");
        cqjl.setCcDate(new Date());
        cqjl.setUserId(id);
        cqjl.setYear(param.getYear());
        cqjl.setCqwc(0);
        ksSsjCqjlMapper.insert(cqjl);
        // 获取所有查询数据并过滤状态为非生产的数据
        List<KsJbxxhz> allQueries = ksJbxxhzMapper.selectAboutMines(param.getTenementType());
        List<KsJbxxhz> nonProductionQueries = allQueries.stream()
                .filter(query -> !"生产".equals(query.getSczt()))
                .collect(Collectors.toList());
        if (param.getPercentage() > allQueries.size()) {
            throw new ServiceException("大于总数量,请重新抽取数据");
        }

        // 状态为生产的查询数据
        List<KsJbxxhz> collect = allQueries.stream().filter(produce -> ScztV3Enum.SC.getDesc().equals(produce.getSczt())).collect(Collectors.toList());
        if (param.getTheStatusIsNumberOfRecordsProduced() > collect.size()) {
            throw new ServiceException("数量不能超过100%，请重新抽取");
        }

        // 根据比例生成样本
        int sampleSize = Math.min(allQueries.size() - collect.size(),
                ksJbxxhzVo.getPercentage() - param.getTheStatusIsNumberOfRecordsProduced());
        if (sampleSize < 0) {
            throw new ServiceException("数量不能超过100%，请重新抽取");
        }
        List<KsJbxxhz> shuffledNonProductionQueries = new ArrayList<>(nonProductionQueries);
        Collections.shuffle(shuffledNonProductionQueries);
        List<KsJbxxhz> sampledQueries = shuffledNonProductionQueries.stream()
                .limit(sampleSize)
                .collect(Collectors.toList());

        // 按照生产状态过滤
        List<KsJbxxhz> shuffledProductionQueries = new ArrayList<>(collect);
        Collections.shuffle(shuffledProductionQueries);
        List<KsJbxxhz> filteredProductionQueries = shuffledProductionQueries.stream()
                .limit(param.getTheStatusIsNumberOfRecordsProduced())
                .collect(Collectors.toList());

        // 合并
        List<KsJbxxhz> combinedQueries = Stream.concat(filteredProductionQueries.stream(), sampledQueries.stream())
                .collect(Collectors.toList());
        int i = 0;//自增id
        List<KsJbxxhzVo> jbxxhzDtos = new ArrayList<>();
        // 遍历合并后的查询数据
        for (KsJbxxhz combinedQuery : combinedQueries) {
            addAnExtractionResult(combinedQuery,ksJbxxhzVo.getYear(),cqjl.getId());
            // 创建单个Dto对象并设置属性
            KsJbxxhzVo dto = new KsJbxxhzVo();
            dto.setChillId(combinedQuery.getChillId());
            dto.setId(++i);
            dto.setKcfs(combinedQuery.getKcfs());
            dto.setXkzh(combinedQuery.getXkzh());
            dto.setKsmc(combinedQuery.getKsmc());
            dto.setSzxzqmc(combinedQuery.getSzxzqmc());
            dto.setKz(combinedQuery.getKz());
            dto.setKzmc(combinedQuery.getKzmc());
            dto.setSczt(combinedQuery.getSczt());
            jbxxhzDtos.add(dto);
        }
        dtos.addAll(jbxxhzDtos);
        return dtos;
    }

    /**
     * 添加抽取结果
     * @author 齐浩宽
     */
    private void addAnExtractionResult(KsJbxxhz combinedQuery, String year, Integer id) {
        combinedQuery.setChillId(id);
        // 创建抽取结果类
        KsSsjCqjg cqjg = new KsSsjCqjg();
        cqjg.setXkzh(combinedQuery.getXkzh()); // 许可证号
        cqjg.setKsmc(combinedQuery.getKsmc()); // 矿山名称
        cqjg.setYear(year); // 年份
        cqjg.setCqjlId(id); // 抽取记录id
        cqjg.setKyqr(combinedQuery.getKyqr()); // 矿业权人
        cqjg.setKz(combinedQuery.getKz()); // 矿种
        cqjg.setKcfs(combinedQuery.getKcfs()); // 开采方式
        cqjg.setYxqq(combinedQuery.getYxqq()); // 期起
        cqjg.setYxqz(combinedQuery.getYxqz()); // 期止
        cqjg.setSczt(combinedQuery.getSczt()); // 生产状态
        cqjg.setBc(0);
        Optional<BasicRegion> checkTheCountyData = findCountyInfo(combinedQuery.getSzxzq());
        //查找县
        cqjg.setXszxzq(checkTheCountyData.get().getAdcd());// 县所在行政区
        cqjg.setXszxzqmc(checkTheCountyData.get().getAdnm());// 县所在行政区名称
        //查找市
        Optional<BasicRegion> checkTheMarketData = findCityInfo(combinedQuery.getSzxzq());
        cqjg.setSszxzq(checkTheMarketData.get().getAdcd());// 市所在行政区
        cqjg.setSszxzqmc(checkTheMarketData.get().getAdnm());// 市所在行政区名称
        ksSsjCqjgMapper.insert(cqjg);
    }


    /**
     * 查询矿山基本信息汇总表 地区 统计
     *
     * @author 齐浩宽
     * @since 2024年5月27日17:06:12
     */
    @Override
    public KsJbVo queryStatistics() {

        KsJbVo dto = new KsJbVo();
        dto.setBoroughs("河北省");
        // 直接查询状态为"生产"的矿山
        List<KsJbxxhz> jbxxhzs = ksJbxxhzMapper.selectAboutMines(DataConstant.KQLX_FOR_CKQ);
        // 计算状态为"生产"的矿山总数
        long productionCount = jbxxhzs.stream()
                .filter(ss -> ss.getSczt() != null && ss.getSczt().equals(ScztV3Enum.SC.getDesc()))
                .count();
        // 获取矿山总数
        dto.setNumberOfTenements(jbxxhzs.size());
        // 计算生产矿山数量
        dto.setTotalNumberOfMines(productionCount);
        return dto;
    }

    /**
     * 查询县名称
     * @author 齐浩宽
     */
    private Optional<BasicRegion> findCountyInfo(String szxzq) {
        LambdaQueryWrapper<BasicRegion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BasicRegion::getAdcd, szxzq);
        List<BasicRegion> regions = basicRegionMapperl.selectList(wrapper);
        return regions.stream().findFirst();
    }

    /**
     * 查询市名称
     * @author 齐浩宽
     */
    private Optional<BasicRegion> findCityInfo(String szxzq) {
        String prefix = szxzq.substring(0, 4);
        String suffix = "00";
        String result = prefix + suffix;

        LambdaQueryWrapper<BasicRegion> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BasicRegion::getAdcd, result);
        List<BasicRegion> regions = basicRegionMapperl.selectList(queryWrapper);
        return regions.stream().findFirst();
    }

    /**
     * 分页查询矿山图层管理数据
     *
     * @param mineLayerDataParam
     * @author 窦凯欣
     */
    @Override
    public TableDataInfo<KsJbxxhzLayerManagementVo> dataAll(MineLayerDataParam mineLayerDataParam)
    {
        TableDataInfo<KsJbxxhzLayerManagementVo> tableDataInfo = new TableDataInfo<>();
        // 查询：可选条件 矿山分类，矿权类型，行政区(数组)，许可证号，日期起，日期止
        List<KsJbxxhz> records = baseMapper.selectList(Wrappers.<KsJbxxhz>lambdaQuery()
                .like(!StringUtil.isNullOrEmpty(mineLayerDataParam.getKsmc()), KsJbxxhz::getKsmc, mineLayerDataParam.getKsmc())
                .eq(mineLayerDataParam.getKsfl() != null, KsJbxxhz::getKsfl, mineLayerDataParam.getKsfl())
                .eq(mineLayerDataParam.getKqlx() != null, KsJbxxhz::getKqlx, mineLayerDataParam.getKqlx())
                .like(!StringUtil.isNullOrEmpty(mineLayerDataParam.getSzxzqmc()), KsJbxxhz::getSzxzqmc, mineLayerDataParam.getSzxzqmc() != null ? mineLayerDataParam.getSzxzqmc().replaceAll("\\s+", "") : null)
                .like(!StringUtil.isNullOrEmpty(mineLayerDataParam.getXkzh()), KsJbxxhz::getXkzh, mineLayerDataParam.getXkzh())
                .ge(!StringUtil.isNullOrEmpty(mineLayerDataParam.getYxqq()), KsJbxxhz::getYxqq, DateUtil.parse(mineLayerDataParam.getYxqq()))
                .le(!StringUtil.isNullOrEmpty(mineLayerDataParam.getYxqz()), KsJbxxhz::getYxqz, DateUtil.parse(mineLayerDataParam.getYxqz())));
        // 得到数据的总数
        int size = records.size();
        // 判断是否查询已挂载数据
        if (mineLayerDataParam.getGstate() != null && mineLayerDataParam.getGstate().equals(KsflEnum.MOUNTED.getCode().toString()))
        {
            // 获取所有的许可证号
            String data = ksTcService.list().stream().map(r -> r.getXkzh()).collect(Collectors.joining(","));
            // 获取许可证对应的数据
            records = records.stream().filter(r -> data.contains(r.getXkzh())).collect(Collectors.toList());
            // 得到当前数据总数
            size = records.size();
        } else if(mineLayerDataParam.getGstate() != null && mineLayerDataParam.getGstate().equals(KsflEnum.UNMOUNTED.getCode().toString()))
        {
            // 获取所有的许可证号
            String data = ksTcService.list().stream().map(r -> r.getXkzh()).collect(Collectors.joining(","));
            // 获取许可证对应的数据
            records = records.stream().filter(r -> ! data.contains(r.getXkzh())).collect(Collectors.toList());
            // 得到当前数据总数
            size = records.size();
        }
        // 如果上面查询有数据则进行方法体中的操作
        if(size != 0)
        {
            // Step 1: 从记录中提取所有不同的 Xkzh 值
            List<String> xkzhList = records.stream().map(KsJbxxhz::getXkzh).distinct().collect(Collectors.toList());
            // Step 2: 执行批处理查询以获取计数
            Map<String, Long> xkzhCountMap = this.countByXkzhBatch(xkzhList);
            // Step 3: 设置每条记录的 Qishu 值
            records = records.stream().filter(r -> r.getKqlx() == TenementType.MININGRIGHTS.getCode() || r.getKqlx() == TenementType.PROSPECTINGRIGHTS.getCode())
                    .map(v -> {
                        v.setQishu(xkzhCountMap.getOrDefault(v.getXkzh(), 0L));
                        return v;
                    }).collect(Collectors.toList());
            size = records.size();
        }
        // 分页处理 从请求头中得到分页的参数信息
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        // 对数据进行分页 (当前页数 - 1) * 每页总数, 每页总数
        records = records.stream().skip(((pageNum <= 0 ? 1 : pageNum) - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        // 将查询到的数据拷贝到Vo返回类中
        List<KsJbxxhzLayerManagementVo> data = BeanUtil.copyToList(records, KsJbxxhzLayerManagementVo.class);
        // 设置返回结果信息
        tableDataInfo.setTotal(size);
        tableDataInfo.setRows(data);
        return tableDataInfo;
    }

    /**
     * 根据许可证号集合查询总数并返回
     *
     * @param xkzhList
     * @author 窦凯欣
     */
    public Map<String, Long> countByXkzhBatch(List<String> xkzhList)
    {
        // 查询当前许可证号的挂载总数
        return baseMapper.selectCountByXkzhBatch(xkzhList).stream()
                .collect(Collectors.toMap(KsTcCountParam::getXkzh, KsTcCountParam::getCount));
    }

    /**
     * 查询行政区二级数据
     *
     * @author 窦凯欣
     */
    @Override
    public List<BasicRegion> getXzq()
    {
        // 查询所有数据
        List<BasicRegion> basicRegions = basicRegionMapperl.selectList(null);
        // 得到所有二级数据
        List<BasicRegion> res = basicRegions.stream()
                .filter(r -> r.getLevel() == DataConstant.REGION_LEVEL_OF_CITY).collect(Collectors.toList());
        // 过滤所有二级数据
        List<BasicRegion> collect = res.stream()
                .filter(r -> r.getLevel() == DataConstant.REGION_LEVEL_OF_CITY)
                .map(m -> {
                    // 判断如果没有子级了那么就赋值为一个空的集合
                    if (m.getChild() == null) m.setChild(new ArrayList<>());
                    // 如果有子级将当前对象的Child集合中进行设置
                    m.setChild(basicRegions.stream()
                            // 根据adcd字符的拼接来判断是否为谋二级下的三级数据然后过滤所有三级数据 满足条件则进行添加
                            .filter(r ->
                            {
                                //  获取字符串的后两位
                                int i = r.getAdcd().length() - 2;
                                // 从0开始截取到后两位的位置并加上00，然后跟二级数据的adcd进行比较如果相同说明就是当前二级的三级数据
                                boolean f = (r.getAdcd().substring(0, i) + "00").equals(m.getAdcd());
                                // 满足上面的判断f条件并且满足三级数据则返回为true进行添加
                                return r.getLevel() == DataConstant.REGION_LEVEL_OF_COUNTY && f;
                            }).map(i -> {
                                // 判断如果没有子级了那么就赋值为一个空的集合
                                if (i.getChild() == null) i.setChild(new ArrayList<>());
                                // 返回对象，将stream转换为集合并返回
                                return i;}).collect(Collectors.toList()));
                    // 返回对象，将stream转换为集合并返回
                    return m;}).collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取矿权类型下拉框
     *
     * @author 窦凯欣
     */
    @Override
    public List<TenementType> getKql()
    {
        // 获取枚举类的菜单数据
        List<TenementType> allEnum = TenementType.getAllEnum();
        return allEnum;
    }

    /**
     * 查询矿山基本信息汇总分页列表。
     * 2024/5/27 19:01
     *
     * @param ksJbxxhzRequestBodyParam 矿山基本信息汇总实体，用于过滤查询条件。
     * @return 返回一个包含矿山基本信息汇总列表和总数的Map对象。
     * 郭伟明
     */
    @Override
    public TableDataInfo selectKsJbxxhzList(KsJbxxhzRequestBodyParam ksJbxxhzRequestBodyParam)
    {
        LambdaQueryWrapper<KsJbxxhz> wrapper = new LambdaQueryWrapper<>();
        // 根据传入的条件动态构建查询条件
        wrapper.like(ksJbxxhzRequestBodyParam.getKsmc() != null, KsJbxxhz::getKsmc, ksJbxxhzRequestBodyParam.getKsmc())
                .eq(ksJbxxhzRequestBodyParam.getKsfl() != null, KsJbxxhz::getKsfl, ksJbxxhzRequestBodyParam.getKsfl())
                .like(!StringUtil.isNullOrEmpty(ksJbxxhzRequestBodyParam.getSzxzqmc()), KsJbxxhz::getSzxzqmc, ksJbxxhzRequestBodyParam.getSzxzqmc() != null ? ksJbxxhzRequestBodyParam.getSzxzqmc().replaceAll("\\s+", "") : null)
                .like(ksJbxxhzRequestBodyParam.getXkzh() != null, KsJbxxhz::getXkzh, ksJbxxhzRequestBodyParam.getXkzh())
                .and(ksJbxxhz -> ksJbxxhz.in(KsJbxxhz::getKqlx, Arrays.asList(1, 2)))
                .eq(ksJbxxhzRequestBodyParam.getKqlx() != null, KsJbxxhz::getKqlx, ksJbxxhzRequestBodyParam.getKqlx())
                .ge(ksJbxxhzRequestBodyParam.getYxqq()!= null, KsJbxxhz::getYxqq, DateUtil.parse(ksJbxxhzRequestBodyParam.getYxqq()))
                .le(ksJbxxhzRequestBodyParam.getYxqz()!= null, KsJbxxhz::getYxqz, DateUtil.parse(ksJbxxhzRequestBodyParam.getYxqz()));

        // 构建分页请求，并执行查询
        List<KsJbxxhz> records = ksJbxxhzMapper.selectList(wrapper);
        int total = records.size();

        // 处理挂载状态
        if (ksJbxxhzRequestBodyParam.getGstate() != null) {
            Set<String> xkzhSet = records.stream().map(KsJbxxhz::getXkzh).collect(Collectors.toSet());
            if (!xkzhSet.isEmpty()) {
                Map<String, Long> xkzhCountMap = ksDomMapper.selectList(new QueryWrapper<KsDom>().in("xkzh", xkzhSet))
                        .stream()
                        .collect(Collectors.groupingBy(KsDom::getXkzh, Collectors.counting()));

                if (ksJbxxhzRequestBodyParam.getGstate().equals(String.valueOf(KsflEnum.MOUNTED.getCode()))) {
                    records = records.stream()
                            .filter(r -> xkzhCountMap.containsKey(r.getXkzh()) && xkzhCountMap.get(r.getXkzh()) != 0)
                            .peek(r -> r.setNumber(xkzhCountMap.get(r.getXkzh())))
                            .collect(Collectors.toList());
                } else if (ksJbxxhzRequestBodyParam.getGstate().equals(String.valueOf(KsflEnum.UNMOUNTED.getCode()))) {
                    records = records.stream()
                            .filter(r -> !xkzhCountMap.containsKey(r.getXkzh()) || xkzhCountMap.get(r.getXkzh()) == 0)
                            .collect(Collectors.toList());
                }
                total = records.size();
            }
        }

        // 将矿权类型1映射为“采矿权”，将矿权类型2映射为“探矿权”
        for (KsJbxxhz record : records) {
            if (record.getKqlx() == TenementType.MININGRIGHTS.getCode()) {
                record.setKqlxname("采矿权");
            } else if (record.getKqlx() == TenementType.PROSPECTINGRIGHTS.getCode()) {
                record.setKqlxname("探矿权");
            }
        }

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        records = records.stream().skip(((pageNum <= 0 ? 1 : pageNum) - 1) * pageSize).limit(pageSize).collect(Collectors.toList());

        // 返回包含筛选后的记录列表和总记录数的对象
        return new TableDataInfo(records, total);
    }

    /**
     * 便捷回显
     * 根据提供的 KsJbxxhzp 和 KsDom 对象，检索包含 KsDomDto 对象列表的映射。
     * 2024/5/27 19:01
     * @param ksDomParam 包含基本信息的对象，包括许可证编号 (xkzh)。
     * @param ksDomParam     包含领域特定信息的对象（此方法中未使用）。
     * @param pageable  分页信息的对象（此方法中未使用）。
     * @return 包含 KsDomDto 对象列表的映射，键为 "domDtos"。
     * 郭伟明
     */
    @Override
    public Map<String,Object> EditEcho(KsDomParam ksDomParam, Pageable pageable) {
        // 用于存储响应数据的映射
        Map<String, Object> responseData = new HashMap<>();
        // 用于存储 DTO 对象的列表
        List<KsDomVo> ksDomVos = new ArrayList<>();
        // 检查许可证编号 (xkzh) 是否不为空
        if (ksDomParam.getXkzh() != null) {
            // 根据许可证编号检索 KsDom 对象列表
            List<KsDom> ksDoms = ksDomMapper.selectList(
                    new LambdaQueryWrapper<KsDom>().in(KsDom::getXkzh, ksDomParam.getXkzh())
            );
            // 将每个 KsDom 对象转换为 KsDomDto 对象并添加到列表中
            ksDoms.forEach(dom ->
            {
                KsDomVo domDto = new KsDomVo();
                domDto.setId(dom.getId());
                // 设置名称
                domDto.setMc(dom.getMc());
                // 设置xkzh
                domDto.setXkzh(dom.getXkzh());
                // 设置 URL
                domDto.setUrl(dom.getUrl());
                domDto.setDelState(0);

                // 设置日期，格式为 "year-month"
                domDto.setDataTime(String.valueOf(dom.getYear() + "-" + dom.getMonth()));
                // 将DTO添加到列表中
                ksDomVos.add(domDto);
            });
        }
        // 将DTO列表放入响应数据的映射中
        responseData.put("domDtos", ksDomVos);
        // 返回响应数据的映射
        return responseData;
    }

    /**
     * 获取下拉框（许可证号、矿山名称）
     *
     * @author 郭梓强
     * @since 2024年5月27日10:46:12
     */
    @Override
    public KsJbXxHzDropdownVo selWhole(KsJbxxhzRequestParam ksJbxxhzRequestParam)
    {
        // 调用Mapper层查询数据库，根据查询条件筛选矿山基本信息列表
        List<KsJbxxhz> ksList = ksJbxxhzMapper.selectList(Wrappers.<KsJbxxhz>lambdaQuery()
                .orderByDesc(KsJbxxhz::getId)//倒序
                // lambdaQuery 构建查询条件
                .eq(!(ksJbxxhzRequestParam.getKqlx() == null), KsJbxxhz::getKqlx, ksJbxxhzRequestParam.getKqlx()) // 矿权类型
        ).stream().filter(r -> r.getKsfl() <= JgKsFlEnum.LSYL.getCode()).collect(Collectors.toList());

        // 创建两个集合，用于存储许可证号和矿山名称
        List<String> xkzhList = new ArrayList<>(); // 存储许可证号
        List<String> ksmcList = new ArrayList<>(); // 存储矿山名称

        // 遍历查询结果，将许可证号和矿山名称分别存入集合中
        for (KsJbxxhz ks : ksList) {
            xkzhList.add(ks.getXkzh()); // 将许可证号添加到许可证号列表中
            ksmcList.add(ks.getKsmc()); // 将矿山名称添加到矿山名称列表中
        }

        // 对集合进行去重
        xkzhList = xkzhList.stream().distinct().collect(Collectors.toList()); // 去重许可证号列表
        ksmcList = ksmcList.stream().distinct().collect(Collectors.toList()); // 去重矿山名称列表

        // 创建响应对象并设置集合
        KsJbXxHzDropdownVo response = new KsJbXxHzDropdownVo();
        response.setXkzh(xkzhList); // 设置许可证号列表
        response.setKsmc(ksmcList); // 设置矿山名称列表

        return response; // 返回响应对象
    }

    /**
     * 获取全部矿山基本信息汇总-条件（分页）
     *
     * @author 郭梓强
     * @since 2024年5月27日20:21:12
     */
    @Override
    public  List<KsJbxxhz> selInformation(KsJbxxhzRequestParam ksJbxxhzRequestParam) {

        //构造返回封装类
        List<KsJbxxhz> ksJbxxhzs = ksJbxxhzMapper.selectList(Wrappers.<KsJbxxhz>lambdaQuery()
                // lambdaQuery 构建查询条件
                .eq(!(ksJbxxhzRequestParam.getKqlx() == null), KsJbxxhz::getKqlx, ksJbxxhzRequestParam.getKqlx())//矿权类型()
                .eq(!(ksJbxxhzRequestParam.getId() == null), KsJbxxhz::getId, ksJbxxhzRequestParam.getId())//id
                .eq(!(ksJbxxhzRequestParam.getKsfl() == null), KsJbxxhz::getKsfl, ksJbxxhzRequestParam.getKsfl())//矿山分类
                .like(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getKsmc()), KsJbxxhz::getKsmc, ksJbxxhzRequestParam.getKsmc())//矿山名称
                .like(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getXkzh()), KsJbxxhz::getXkzh, ksJbxxhzRequestParam.getXkzh())//许可证号
                .like(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getSzxzqmc()), KsJbxxhz::getSzxzqmc, ksJbxxhzRequestParam.getSzxzqmc())//所在行政区名称
                .eq(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getKcfs()), KsJbxxhz::getKcfs, ksJbxxhzRequestParam.getKcfs())//开采方式
                .like(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getDz()), KsJbxxhz::getDz, ksJbxxhzRequestParam.getDz())//地址
                .ge(ksJbxxhzRequestParam.getYxqq() != null, KsJbxxhz::getYxqq, ksJbxxhzRequestParam.getYxqq())//有效期起
                .le(ksJbxxhzRequestParam.getYxqz() != null, KsJbxxhz::getYxqz, ksJbxxhzRequestParam.getYxqz())//有效期止
                .le(KsJbxxhz::getKsfl, JgKsFlEnum.LSYL.getCode())//筛选
                .orderByDesc(KsJbxxhz::getId)//倒序
        );
        return ksJbxxhzs;
    }

    @Override
    public List<KsJbXxHzReturnVo> Transformation(List<KsJbxxhz> ksJbxxhzList) {
        // 查询所有ZdJjLx对象
        List<ZdJjLx> zdJjLxes = zdJjLxMapper.selectList(null);
        Map<Integer, ZdJjLx> rollingDetailMap = zdJjLxes.stream()
                .collect(Collectors.toMap(ZdJjLx::getJjlxdm, obj -> obj));
        List<KsJbXxHzReturnVo> ksJbXxHzReturnVos = new ArrayList<>();
        for (KsJbxxhz ksJbxxhz : ksJbxxhzList) {
            KsJbXxHzReturnVo ksJbXxHzReturnVo = new KsJbXxHzReturnVo();
            org.springframework.beans.BeanUtils.copyProperties(ksJbxxhz, ksJbXxHzReturnVo);
            ZdJjLx zdJjLx = rollingDetailMap.get(ksJbxxhz.getJjlx());
            if (zdJjLx != null) {
                ksJbXxHzReturnVo.setJjlxmc(zdJjLx.getJjlxmc());
            }
            ksJbXxHzReturnVos.add(ksJbXxHzReturnVo);
        }
        return ksJbXxHzReturnVos;
    }

    /**
     * 新设-矿山基本信息汇总
     *
     * @author 郭梓强
     * @since 2024年5月27日20:27:32
     */
    @Override
    public boolean addInformation(KsJbxxhzRequestParam ksJbxxhzRequestParam) throws InvocationTargetException, IllegalAccessException {

        // 判断许可证号是否重复
        if (StringUtils.isNotBlank(ksJbxxhzRequestParam.getXkzh())) {
            List<KsJbxxhz> existing = ksJbxxhzMapper.selectList(new LambdaQueryWrapper<KsJbxxhz>()
                            .eq(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getKsmc()), KsJbxxhz::getKsmc, ksJbxxhzRequestParam.getKsmc())//矿山名称
                    .or().eq(!StringUtil.isNullOrEmpty(ksJbxxhzRequestParam.getXkzh()), KsJbxxhz::getXkzh, ksJbxxhzRequestParam.getXkzh())//许可证号
            );
            // 查询结果不为空且不为空列表
            if (!existing.isEmpty()) {
                throw new RuntimeException("许可证号已存在或矿山名称已注册");
            }
        }
        KsJbxxhz ksJbxxhz = new KsJbxxhz();
        BeanUtils.copyProperties(ksJbxxhz,ksJbxxhzRequestParam);
        int insert = ksJbxxhzMapper.insert(ksJbxxhz);
        // 如果受影响的行数大于 0，则表示新设成功，返回 true；否则返回 false
        return insert > 0;
    }

    /**
     * 删除-矿山基本信息汇总（id）
     *
     * @author 郭梓强
     * @since 2024年5月27日20:36:41
     */
    @Override
    public boolean delJgKsJbXxHz(Integer id) {
        //根据id查询当前的许可证号
        KsJbxxhz ksJbxxhzs = ksJbxxhzMapper.selectById(id);

        //当前数据是否存在校验
        existenceVerification(ksJbxxhzs);

        int i = ksJbxxhzMapper.deleteById(id);
        // 如果受影响的行数大于 0，则表示删除成功，返回 true；否则返回 false
        return i > 0;
    }

    /**
     * 根据删除id查询当前数据是否包含文件或遥感检测图
     *
     * @author 郭梓强
     * @since 2024年6月3日11:56:11
     */
    private void existenceVerification(KsJbxxhz ksJbxxhzs) {
        // 查询与许可证号相关的文件列表
        List<KsFile> ksFiles = ksFileMapper.selectList(Wrappers.<KsFile>lambdaQuery()
                .eq(KsFile::getXkzh, ksJbxxhzs.getXkzh()) // 许可证号
        );

        // 查询与许可证号相关的遥感检测图列表
        List<KsYgJct> ksYgJcts = ksYgJctMapper.selectList(Wrappers.<KsYgJct>lambdaQuery()
                .eq(KsYgJct::getXkzh, ksJbxxhzs.getXkzh()) // 许可证号
        );

        // 如果存在相关文件或遥感检测图，则抛出异常
        if (ksFiles.size() > 0 || ksYgJcts.size() > 0) {
            throw new RuntimeException("当前数据包含已上传文件或遥感检测图无法直接删除");
        }
    }

    /**
     * 延续-矿山基本信息汇总
     *
     * @author 郭梓强
     * @since 2024年5月27日20:37:42
     */
    @Override
    public boolean updJgKsJbXxHz(KsJbxxhzRequestParam ksJbxxhzRequestParam) throws InvocationTargetException, IllegalAccessException {
        // 去重校验
        Deduplication(ksJbxxhzRequestParam);
        // 创建新的KsJbxxhz对象，用于更新
        KsJbxxhz ksJbxxhz = new KsJbxxhz();
        // 将ksJbxxhzRequestParam的属性拷贝到ksJbxxhz对象中
        BeanUtils.copyProperties(ksJbxxhz,ksJbxxhzRequestParam);
        // 执行更新操作
        int updatedById = ksJbxxhzMapper.updateById(ksJbxxhz);
        // 如果受影响的行数大于 0，则表示更新成功，返回 true；否则返回 false
        return updatedById > 0;
    }

    private void Deduplication(KsJbxxhzRequestParam ksJbxxhzRequestParam) {
        KsJbxxhz existingRecord = ksJbxxhzMapper.selectOne(
                Wrappers.lambdaQuery(KsJbxxhz.class)
                        .eq(KsJbxxhz::getXkzh, ksJbxxhzRequestParam.getXkzh())
        );

        // 如果存在重复记录且不是当前记录，则抛出异常
        if (existingRecord != null && !existingRecord.getId().equals(ksJbxxhzRequestParam.getId())) {
            throw new RuntimeException("许可证号已存在");
        }

    }
}
